﻿using Farming.Domain;
using Farming.Domain.Input;
using Farming.Domain.Output;
using Farming.Repositories;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
using QRCoder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace Farming.Service
{
    [DynamicWebApi]
    [ApiExplorerSettings(GroupName = "v1")]
    [Authorize]
    public class GoodsService : IDynamicWebApi, IGoodsService
    {
        protected readonly IRepository<Goods> goods;
        protected readonly IRepository<GoodsType> goodsType;
        protected readonly IConfiguration configuration;
        protected readonly IWebHostEnvironment host;
        public GoodsService(IRepository<Goods> goods, IRepository<GoodsType> goodsType, IConfiguration configuration, IWebHostEnvironment host)
        {
            this.configuration = configuration;
            this.host = host;
            this.goods = goods;
            this.goodsType = goodsType;
        }

        [HttpPost]
        public async Task<int> AddGoods(AddGoodsInput a)
        {
            try
            {
                Goods g = new()
                {
                    Batches = a.Batches,
                    CerNumber = a.CerNumber,
                    Company = a.Company,
                    GoodsTypeId = a.GoodsTypeId,
                    Expiration = a.Expiration,
                    GoodsName = a.GoodsName,
                    Image = a.Image,
                };

                return await goods.InSertAsync(g);
            }
            catch (Exception)
            {

                throw;
            }
        }
        [HttpGet]
        public async Task<List<GoodsType>> GetGoods()
        {
            try
            {
                var data = goodsType.GetAllAsync().Result.Where(t => !t.IsDeleted).ToList();
                return data;
            }
            catch (Exception)
            {
                throw;
            }
        }

        [HttpPost]
        public string UploadImage(IFormFile file)
        {
            string fileName = Directory.GetCurrentDirectory() + @"/wwwroot/Image/" + file.FileName;
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                file.CopyTo(fs);
                fs.Flush();
            }
            return "https://localhost:44395/Image/" + file.FileName;
        }
        [HttpGet]
        public async Task<List<GetGoodsListOutput>> GetGoodsList()
        {
            var data = (from goods in await goods.GetAllAsync()
                        join goodsType in await goodsType.GetAllAsync()
                        on goods.GoodsTypeId equals goodsType.GoodsTypeId
                        where !goods.IsDeleted
                        select new GetGoodsListOutput
                        {
                            Batches = goods.Batches,
                            CerNumber = goods.CerNumber,
                            Company = goods.Company,
                            Expiration = goods.Expiration,
                            GoodsId = goods.GoodsId,
                            GoodsName = goodsType.GoodsTypeName,
                            GoodsTypeName = goodsType.GoodsTypeName,
                            Image = goods.Image
                        }).ToList();
            return data;
        }
        [HttpPut]
        public async Task<int> UpdateGoods(Goods g)
        {
            try
            {
                g.LastModifierName = g.LastModifierName;
                g.LastModifyTime = DateTime.Now;
                var re = goods.UpdateAsync(g);
                return await re;
            }
            catch (Exception)
            {

                throw;
            }
        }
        [HttpGet("/Goods/FindGoodsById")]
        public async Task<object> FindGoodsById(int id)
        {
            try
            {
                var data = goods.GetAllAsync().Result.FirstOrDefault(t => t.GoodsId == id);
                return data;
            }
            catch (Exception)
            {

                throw;
            }
        }
        //md5加密
        public static string GetMd5(string str)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(str);
            var md5 = System.Security.Cryptography.MD5.Create();
            byte[] result = md5.ComputeHash(bytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                sb.Append(result[i].ToString("X2"));
            }
            return sb.ToString();
        }
        [HttpGet]
        
        public async Task<int> DeleteGoods(int id)
        {
            var goods = await this.goods.GetByIdAsync(id);
            goods.IsDeleted = true;
            return await this.goods.UpdateAsync(goods);
        }


        [HttpPost]
        public async Task<dynamic> UploadFile(IFormFile file)
        {
            //文件类型
            var extFiles = configuration["AllowFileExt"].Split("|");

            var fileExt = Path.GetExtension(file.FileName);

            if (!extFiles.Contains(fileExt))
            {
                throw new Exception("文件类型不正确");
            }
            //判断文件大小
            if (file.Length / 1024 > 100)
            {
                throw new Exception("文件太大了");
            }
            //存储位置和文件重命名
            var dirPath = $"/images/{DateTime.Now.ToString("yyyy")}/{DateTime.Now.ToString("yyyyMMdd")}";
            if (!Directory.Exists($"{host.WebRootPath}{dirPath}"))
            {
                Directory.CreateDirectory($"{host.WebRootPath}{dirPath}");
            }
            Random random = new Random();
            var newFileName = $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}_{random.Next(100, 999)}{fileExt}";
            using (FileStream filestream = new FileStream($"{host.WebRootPath}{dirPath}/{newFileName}", FileMode.Create))
            {
                await file.CopyToAsync(filestream);
            }
            return (new
            {
                Path = $"{dirPath}/{newFileName}"
            });
        }




    }
}
